This is a sample of pbuffers on Mac OS X. It renders one of a number of mathematically defined surfaces into the Pbuffer and then uses this as the texture from drawing on the faces of a simple cube in the windowed drawable.  One can note the transparent section on the rendered content from the cleared alpha of the pbuffer texture.  It builds on the GLCarbonAGLWindow sample thus has much of the same support code.  See that sample for more information on the surrounding support code.

This sample specifically shows how to use a single context for both the window and the pbuffer drawables, switching between them for drawing, keeping consistent state.  Two non-standard techniques are needed to make this sample possible.  

First one uses the buffer naming facilities in AGL to allow a dummy context to share the windowed drawable with the main context in the app.  Since AGL will destroy the accelerated surface associated with a windowed drawable when all contexts are detached, keeping the dummy context attached to the surface ensures the accelerated surface and its contents are maintained.  

The second technique to work around an issue in AGL with drawable setting in Mac OS X v10.3.  When AGL sets a Pbuffer as the drawable using aglSetPBuffer internal bookkeeping is not correctly updated resulting in AGL ignoring subsequent calls to aglSetDrawable when trying to set the drawable back to the window.  The simple work around is to set the drawable to NULL then set it to the window.  This should not cause measurable overhead and will ensure the drawable is set back to the window properly.  It is expected this issue will be addressed in the future though this work around should always function properly.

The pbuffer code has been pulled out of the context creation and OpenGL drawing for sample purposes, developers are free to integrate this creation process.  When using two drawables with one context, one must ensure the viewport and matrices are set correctly for separate drawing in the pbuffer and window.

Specifically in main.c, the following marks indicate points of interest in the source:

*** create pbuffer ***
aglCreatePBuffer is called to create the pixel buffer after the context has been created.  No new context nor pixel format is created here. 

*** set pbuffer as drawable ***
aglSetPBuffer is equivalent to aglSetDrawable for pbuffers (always use aglSetPBuffer when to set the pbuffer as the drawable and aglSetDrawable to set a window as a drawable).  It takes the virtual screen from the target context and uses this to choose the renderer for drawing into the pbuffer.  Think of the virtual screen as an index to hardware to use for rendering. Optional one can target a specific mipmap level or cube face for mipmapped and cube map Pbuffers respectively.  Lastly, note this is only called if we actually need to draw into the pbuffer to remove the overhead of needless drawable and renderer changes.

*** dispose pbuffer ***
Context is set to current then the texture being used as the Pbuffer texture is disposed.  Following this aglDestroyPBuffer is called to destroy the Pbuffers buffers and any memory associated with it.

*** draw to pbuffer ***
This code draws the to Pbuffer.  Note, the correct OpenGL viewport, projection and modelview matrices have been set prior to drawing each time to account for these changing when drawing in the window.

There are two important notes.  First, we use a simple method to limit the pbuffer updates to once every 1/60th of a second, when the renderer of the window (e.g., its virtual screen) changes, or when settings change that affect the appearance of the pbuffer's content.  This brings up the second point.  The Pbuffer has its own buffers and thus is persistent across draws.  The buffers are not affected by drawing to the window and thus only need to be updated whenever changes are required.

*** bind pbuffer as texture ***
The routine bindPbuffer encapsulates pbuffer texture binding. This function binds the Pbuffer as a texture to allow drawing from it.  On the first pass, when no texture name as been created, it creates a texture name, binds to this object, sets the texture parameter for no mipmapping then calls aglTexImagePBuffer which is the Pbuffer equivalent to glTexImage.  If a texture object has been created already it just binds to this object.  Note, if one is using mipmaps with the Pbuffer and the content has changed aglTexImagePBuffer should be re-issued for the mipmap changes to be picked up (the texture does not need to be deleted, just re-issue aglTexImagePBuffer to get mipmap updates).

*** texture from pbuffer ***
This code simple calls the previous bindPbuffer routine and draws content (in this case a cube) using the Pbuffer as the texture.

Lastly, Pbuffers correspond to rules of texturing as any other texture would, such as 2D textures needing to be power of two.

This sample also demonstrates these same basic elements from the Parent Carbon OpenGL sample.

Comments and bugs are welcome at: <http://developer.apple.com/bugreporter>

Requirements: Xcode, Mac OS X v10.3 or later.
